package triggerhelper.controllers;

import java.awt.Color;
import java.io.*;
import java.net.URISyntaxException;
import java.util.ArrayList;
import javax.swing.*;
import triggerhelper.dataHolders.*;
import triggerhelper.helperClasses.*;
import triggerhelper.triggerCreator;

public class MenuBarController {

    private static final SimpleFileFilter tprFilter = new SimpleFileFilter("tpr", "Trigger Project Files");
    private static final SimpleFileFilter trfFilter = new SimpleFileFilter("trf", "Trigger Files");

    private triggerCreator theParent;
    private JTextField fTrigName;
    private JLabel mainProject, mainTrigger;
    private JTabbedPane mainTabPane;
    private JList listTriggers;
    private DefaultListModel listModel;
    private TriggerProject currentProject;

    public MenuBarController(triggerCreator a) {
        theParent = a;
        setEasyAccessFields(a);
        listModel = (DefaultListModel)listTriggers.getModel();
    }

    private void setEasyAccessFields(triggerCreator a){
        fTrigName = a.getfTrigName();
        mainProject = a.getMainProject();
        mainTrigger = a.getMainTrigger();
        mainTabPane = a.getMainTabPane();
        listTriggers = a.getListTriggers();
        currentProject = a.getCurrentProject();
    }

    //Methods that the Gui Calls
    public void newProject() {
        //first check to see if current project has been modified and not saved
        int option = checkIfSaved();
        if (option != 2 && option != JOptionPane.CLOSED_OPTION) {
            //now ask for a name to the project
            String projectName = "";
            boolean verified = false;
            while (!verified) {
                projectName = JOptionPane.showInputDialog(theParent, "Name your project : ");
                if (projectName == null){
                    return;
                } else if ((Character.isLetter(projectName.charAt(0))) && InputErrorChecking.isAlphaNumeric(projectName)) {
                    verified = true;
                } else {
                    JOptionPane.showMessageDialog(theParent, "I'm sorry, the name you typed must start with a letter," +
                                                             " and must be alphanumeric.");
                }
            }
            enableMenus();

            mainProject.setText(projectName + "*");

            //Instantiate the current project
            currentProject = new TriggerProject(projectName);
            theParent.setCurrentProject(currentProject);

            //clear list
            DefaultListModel tempModel = (DefaultListModel)listTriggers.getModel();
            tempModel.clear();
        }
    }
    public void openProject(){
        //again check if modified && !saved
        int option = checkIfSaved();
        if (option != 2 && option != JOptionPane.CLOSED_OPTION) {

            //find default folder
//            String startingDir = findDefaultFolder("/images/projectOpenDir");

            //choose project to open
            JFileChooser open = null;
//            if(startingDir != null){
//                open = new JFileChooser(startingDir);
//            }else{
                open = new JFileChooser();
//            }
            open.setAcceptAllFileFilterUsed(false);
            open.addChoosableFileFilter(tprFilter);
            open.setBackground(new Color(219, 228, 255));

            int returned = open.showOpenDialog(theParent);
            if (returned == JFileChooser.APPROVE_OPTION) {
                File projectFile = open.getSelectedFile();

                //keep track of opened dir
                String endingDir = projectFile.getParent();
//                newDefaultFolder("/images/projectOpenDir", endingDir);
                
                TriggerProject tempP = openProjectFile(projectFile);
                if (tempP != null) {
                    //go to first tab
                    mainTabPane.setSelectedIndex(0);
                    //update the current working project
                    updateProject(tempP);
                    enableMenus();
                }
            }//else cancel_option or error_option occurred
        }
    }
    public void saveProject() { //save triggers to project (color coding???????????)
        TriggerProject tempP = currentProject;
        if(tempP == null){
            JOptionPane.showMessageDialog(theParent, "I'm sorry, you are currently not working with a project." +
                                                     "  Try making a new project.");
        }
        else if(tempP.isFileSaved()) {
            mainTabPane.setSelectedIndex(0); //save any unsaved data into current trigger
            tempP.saveTriggers(listModel); //save current triggers into project

            try {
                FileOutputStream fos = new FileOutputStream(tempP.getProjectFileName());
                ObjectOutputStream out = new ObjectOutputStream(fos);
                out.writeObject(tempP);
                out.close();

                tempP.setSaved(true);
                JOptionPane.showMessageDialog(theParent, "Project saved");
                listTriggers.repaint();
                mainProject.setText(tempP.getName());
            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(theParent, "Im sorry, the saving process has been interrupted");
            }
        } else {//hasn't been saved before -> save as
            saveProjectAs();
        }
    }
    public void saveProjectAs() {
        TriggerProject tempP = currentProject;
        if (tempP != null) {

            //get default path
//            String startDir = findDefaultFolder("/images/projectSaveDir");

            //create save as dialog - correct the settings
            JFileChooser saveAs = null;
//            if(startDir != null){
//                saveAs = new JFileChooser(startDir);
//            }else{
                saveAs = new JFileChooser();
//            }
            saveAs.setBackground(new Color(219, 228, 255));
            saveAs.setAcceptAllFileFilterUsed(false);
            saveAs.addChoosableFileFilter(tprFilter);
            saveAs.setApproveButtonText("Save As");
            saveAs.setSelectedFile(new File(tempP.getName()));

            int returned = saveAs.showSaveDialog(theParent);
            if (returned == JFileChooser.APPROVE_OPTION) {

                //new default path
                String endingDir = saveAs.getSelectedFile().getParent();
//                newDefaultFolder("/images/projectSaveDir", endingDir);

                String fileName = "";
                try {
                    File aFile = saveAs.getSelectedFile();
                    if(aFile.isDirectory()){
                        fileName = aFile.getCanonicalPath()  + ".tpr";
                    }else{
                        fileName = aFile.getCanonicalPath();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    System.exit(0);
                }
                tempP.setProjectFileName(fileName);
                File projectFile = new File(tempP.getProjectFileName());
                try {
                    projectFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.exit(0);
                }
                tempP.fileSave();
                saveProject();
            }//else cancel or error_option
        }else{
            JOptionPane.showMessageDialog(theParent, "I'm sorry, you are currently not working with a project." +
                                                     "  Try making a new project.");
        }
    }

    public void importTrigger() {
        //get default dir
//        String startDir = findDefaultFolder("/images/triggerOpenDir");

        //choose trigger to open
        JFileChooser open = null;
//        if(startDir != null){
//            open = new JFileChooser(startDir);
//        }else{
             open = new JFileChooser();
//        }
        open.setAcceptAllFileFilterUsed(false);
        open.addChoosableFileFilter(trfFilter);
        open.setBackground(new Color(219, 228, 255));

        int returned = open.showOpenDialog(theParent);
        if (returned == JFileChooser.APPROVE_OPTION) {
            //write new start dir
            String endDir = open.getSelectedFile().getParent();
//            newDefaultFolder("/images/triggerOpenDir", endDir);

            File triggerFile = open.getSelectedFile();
            SimpleTrigger tempT = openTriggerFile(triggerFile);
            if (tempT != null && !isDuplicate(tempT.getName())) {
                //go to first tab
                mainTabPane.setSelectedIndex(0);
                //update the current working project
                theParent.getTdController().addTrigger(tempT);
            }
        }//else cancel_option or error_option occurred
    }

    private boolean isDuplicate(String name){
        for (int i=0; i < listModel.size(); i++) {
            SimpleTrigger t = (SimpleTrigger)listModel.get(i);
            if (t.getName().equals(name)) {
                JOptionPane.showMessageDialog(theParent, "Trigger name -" + name + "- already exists in your project.\n" +
                                                         "Please change the name of that trigger before importing.");
                return true;
            }
        }
        return false;
    }

    public void saveTrigger() {
        SimpleTrigger tempT = theParent.getCurrentTrigger();
        if(tempT.isFileSaved()) {
            mainTabPane.setSelectedIndex(0); //save any unsaved data into current trigger

            try {
                FileOutputStream fos = new FileOutputStream(tempT.getTriggerFileName());
                ObjectOutputStream out = new ObjectOutputStream(fos);
                out.writeObject(tempT);
                out.close();
                
                tempT.fileSave();
                JOptionPane.showMessageDialog(theParent, "Trigger saved");
            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(theParent, "Im sorry, the saving process has been interrupted");
            }
        } else {//hasn't been saved to file before -> save as
            saveTriggerAs();
        }
    }
    public void saveTriggerAs() {
        SimpleTrigger tempT = theParent.getCurrentTrigger();

//        String defaultSaveAs = findDefaultFolder("/images/triggerSaveDir");

        //create save as dialog - correct the settings
        JFileChooser saveAs = null;
//        if(defaultSaveAs != null){
//            saveAs = new JFileChooser(defaultSaveAs);
//        }else{
            saveAs = new JFileChooser();
//        }
        saveAs.setBackground(new Color(219, 228, 255));
        saveAs.setAcceptAllFileFilterUsed(false);
        saveAs.addChoosableFileFilter(trfFilter);
        saveAs.setApproveButtonText("Save As");
        saveAs.setSelectedFile(new File(tempT.getName()));

        int returned = saveAs.showSaveDialog(theParent);
        if (returned == JFileChooser.APPROVE_OPTION) {
            //write new default folder
            String endingDir = saveAs.getSelectedFile().getParent();
//            newDefaultFolder("/images/triggerSaveDir", endingDir);

            String fileName = "";
            try {
                File aFile = saveAs.getSelectedFile();
                if(aFile.isDirectory()){
                    fileName = aFile.getCanonicalPath() + ".trf";
                }else{
                    fileName = aFile.getCanonicalPath();
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(0);
            }
            tempT.setTriggerFileName(fileName);
            File triggerFile = new File(fileName);
            try {
                triggerFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(0);
            }
            tempT.fileSave();
            saveTrigger();
        }//else cancel or error_option
    }

    public void exit() {
        int option = checkIfSaved();
        if (option != 2 && option != JOptionPane.CLOSED_OPTION) {
            theParent.dispose();
            System.exit(0);
        }
    }

    //Helper methods
    public int checkIfSaved() {
        int option = JOptionPane.NO_OPTION;
        if (currentProject != null) {

            // 1) check project
            boolean isSaved = currentProject.isSaved();

            // 2) go through listModel triggers and check if all are saved
            for (int i=0; i<listModel.size() && isSaved; i++) {
                SimpleTrigger t = (SimpleTrigger)listModel.get(i);
                isSaved = t.isSaved();
            }

            // 3) ask to save if not saved
            if (!isSaved) {
                option = JOptionPane.showConfirmDialog(theParent, "Would you like to save the current project before continuing?");
                if (option == JOptionPane.YES_OPTION) {
                    saveProject();
                }
            }
        }
        
        return option;
    }
    private TriggerProject openProjectFile(File fileName) {
        boolean valid = true;

        TriggerProject openedProject = null;
        FileInputStream fis = null;
        ObjectInputStream in = null;

        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            openedProject = (TriggerProject) in.readObject();
            in.close();
        } catch (IOException e) {
            valid = false;
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            valid = false;
            e.printStackTrace();
        }

        if (!valid) {
            openedProject = null;
        }
        return openedProject;
    }
    private SimpleTrigger openTriggerFile(File fileName) {
        boolean valid = true;

        SimpleTrigger openedTrigger = null;
        FileInputStream fis = null;
        ObjectInputStream in = null;
        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            openedTrigger = (SimpleTrigger) in.readObject();
            in.close();
        } catch (IOException e) {
            valid = false;
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            valid = false;
            e.printStackTrace();
        }

        if (!valid) {
            openedTrigger = null;
        }
        return openedTrigger;
    }
    private void updateProject(TriggerProject tempP) {
        //this is called when the project has opened.  Simply update the data
        //on the first tab - along with the project and first trigger name

        //clear list
        DefaultListModel tempModel = (DefaultListModel)listTriggers.getModel();
        tempModel.clear();

        //initialize list
        ArrayList<SimpleTrigger> tempT = tempP.getTriggers();
        for (SimpleTrigger t: tempT) {
            tempModel.addElement(t);
        }
        if(tempP.hasTriggers()){
            theParent.setCurrentTrigger(tempP.getFirstTrigger());
        }
        listTriggers.setSelectedIndex(0);

        //Update the current project
        currentProject = tempP;
        theParent.setCurrentProject(tempP);
        mainProject.setText(tempP.getName()); //initialize project title
    }

    private void enableMenus() {
        theParent.getFmenuSave().setEnabled(true);
        theParent.getFmenuSaveAs().setEnabled(true);
        theParent.getEmenuOpen().setEnabled(true);
    }

//    private String findDefaultFolder(String relative) {
//        String result = null;
//        String readFile = relativeToFilePath(relative);
//        FileReader fr = null;
//        BufferedReader br = null;
//
//        try{
//            fr = new FileReader(readFile);
//            br = new BufferedReader(fr);
//            result = br.readLine();
//            System.out.println(result);
//            br.close();
//        }catch(IOException e){
//            e.printStackTrace();
//        }
//        return result;
//    }
//
//    private String relativeToFilePath(String relative){
//        String result = null;
//        try {
//            result = getClass().getResource(relative).toURI().getPath();
//        } catch (URISyntaxException ex) {
//            ex.printStackTrace();
//        }
//        return result;
//    }
//
//    private void newDefaultFolder(String relative, String endingDir) {
//        String filePath = relativeToFilePath(relative);
//        FileWriter fw = null;
//        BufferedWriter bw = null;
//
//        try{
//            fw = new FileWriter(filePath);
//            bw = new BufferedWriter(fw);
//            bw.write(endingDir);
//            bw.close();
//        }catch(IOException e){
//            e.printStackTrace();
//        }
//    }
}
